package cn.ctodb.divination.service;

import com.hankcs.hanlp.HanLP;
import net.sourceforge.pinyin4j.PinyinHelper;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Service;

import java.io.UnsupportedEncodingException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.Map;

/**
 * Created by cc on 2017/2/7.
 */
@Service
public class BaseService {

    private String STG[] = {"癸", "甲", "乙", "丙", "丁", "戊", "己", "庚", "辛", "壬"};//十天干
    private String SEDZ[] = {"亥", "子", "丑", "寅", "卯", "辰", "巳", "午", "未", "申", "酉", "戌"};// 十二地支

    public String[] exec(int year, int month, int day, int time) {
        int md;
        int mz = 0;// 月支
        int qyjs;//起运基数
        int yz = 0; // 年支
        int yg = 0; // 年干
        int mg; // 月干
        int yearlast; //从公元0年到目前年份的天数 yearlast

        // 确定节气 yz 月支  起运基数 qyjs
        md = month * 100 + day;
        if (md > 204 && md <= 305) {
            mz = 3;
            qyjs = ((month - 2) * 30 + day - 4) / 3;
        }
        if (md >= 306 && md <= 404) {
            mz = 4;
            qyjs = ((month - 3) * 30 + day - 6) / 3;
        }
        if (md >= 405 && md <= 504) {
            mz = 5;
            qyjs = ((month - 4) * 30 + day - 5) / 3;
        }
        if (md >= 505 && md <= 605) {
            mz = 6;
            qyjs = ((month - 5) * 30 + day - 5) / 3;
        }
        if (md >= 606 && md <= 706) {
            mz = 7;
            qyjs = ((month - 6) * 30 + day - 6) / 3;
        }
        if (md >= 707 && md <= 807) {
            mz = 8;
            qyjs = ((month - 7) * 30 + day - 7) / 3;
        }
        if (md >= 808 && md <= 907) {
            mz = 9;
            qyjs = ((month - 8) * 30 + day - 8) / 3;
        }
        if (md >= 908 && md <= 1007) {
            mz = 10;
            qyjs = ((month - 9) * 30 + day - 8) / 3;
        }
        if (md >= 1008 && md <= 1106) {
            mz = 11;
            qyjs = ((month - 10) * 30 + day - 8) / 3;
        }
        if (md >= 1107 && md <= 1207) {
            mz = 0;
            qyjs = ((month - 11) * 30 + day - 7) / 3;
        }
        if (md >= 1208 && md <= 1231) {
            mz = 1;
            qyjs = (day - 8) / 3;
        }
        if (md >= 101 && md <= 105) {
            mz = 1;
            qyjs = (30 + day - 4) / 3;
        }
        if (md >= 106 && md <= 203) {
            mz = 2;
            qyjs = ((month - 1) * 30 + day - 6) / 3;
        }

        // 确定年干和年支 yg 年干 yz 年支
        if (md >= 204 && md <= 1231) {
            yg = (year - 3) % 10;
            yz = (year - 3) % 12;
        }
        if (md >= 101 && md <= 203) {
            yg = (year - 4) % 10;
            yz = (year - 4) % 12;
        }
        // 确定月干 mg 月干
        if (mz > 2 && mz <= 11) {
            mg = (yg * 2 + mz + 8) % 10;
        } else {
            mg = (yg * 2 + mz) % 10;
        }

        // 从公元0年到目前年份的天数 yearlast
        yearlast = (year - 1) * 5 + (year - 1) / 4 - (year - 1) / 100 + (year - 1) / 400;

        // 计算某月某日与当年1月0日的时间差（以日为单位）yearday
        int yearday = 0;
        for (int i = 1; i < month; i++) {
            switch (i) {
                case 1:
                    yearday = yearday + 31;
                    break;
                case 2:
                    if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0) {
                        yearday = yearday + 29;
                    } else {
                        yearday = yearday + 28;
                    }
                    break;
                case 3:
                    yearday = yearday + 31;
                    break;
                case 4:
                    yearday = yearday + 30;
                    break;
                case 5:
                    yearday = yearday + 31;
                    break;
                case 6:
                    yearday = yearday + 30;
                    break;
                case 7:
                    yearday = yearday + 31;
                    break;
                case 8:
                    yearday = yearday + 31;
                    break;
                case 9:
                    yearday = yearday + 30;
                    break;
                case 10:
                    yearday = yearday + 31;
                    break;
                case 11:
                    yearday = yearday + 30;
                    break;
                case 12:
                    yearday = yearday + 31;
                    break;
            }
        }
        yearday = yearday + day;

        // 计算日的六十甲子数 day60
        int day60 = (yearlast + yearday + 6015) % 60;

        // 确定 日干 dg  日支  dz
        int dg = day60 % 10;
        int dz = day60 % 12;
        // 确定 时干 tg 时支 tz
        int tz = (time + 3) / 2 % 12;
        // tg = (dg * 2 + tz + 8) Mod 10
        int tg;
        if (tz == 0) {
            tg = (dg * 2 + tz) % 10;

        } else {
            tg = (dg * 2 + tz + 8) % 10;
        }

        // 把 年月日时 转换成为 生辰八字
        int yzg = toBz(yz);

        // 月支纳干 mzg
        int mzg = toBz(mz);

        // 日支纳干 dzg
        int dzg = toBz(dz);
        // 时支纳干 tzg
        int tzg = toBz(tz);

        //到此，完成各地支所纳天干的确定任务
        String yg1 = STG[yg];
        String yz1 = SEDZ[yz];
        String mg1 = STG[mg];
        String mz1 = SEDZ[mz];
        String dg1 = STG[dg];
        String dz1 = SEDZ[dz];
        String tg1 = STG[tg];
        String tz1 = SEDZ[tz];

        return new String[]{yg1, yz1, mg1, mz1, dg1, dz1, tg1, tz1};
    }

    private int toBz(int a) {
        switch (a) {
            case 1:
                return 0;
            case 2:
                return 6;
            case 3:
                return 1;
            case 4:
                return 2;
            case 5:
                return 5;
            case 6:
                return 3;
            case 7:
                return 4;
            case 8:
                return 6;
            case 9:
                return 7;
            case 10:
                return 8;
            case 11:
                return 5;
            case 0:
                return 9;
        }
        return 0;
    }

    public String[] exec(String scbz) {
        DateTimeFormatter f = DateTimeFormatter.ofPattern("yyyyMMddHH");
        LocalDateTime dateTime = LocalDateTime.parse(scbz, f);
        int year = dateTime.getYear();
        int month = dateTime.getMonthValue();
        int day = dateTime.getDayOfMonth();
        int hour = dateTime.getHour();
        return exec(year, month, day, hour);
    }

    public Map<String, String> nayin = new HashMap<>();

    {
        nayin.put("甲子", "海中金");
        nayin.put("乙丑", "海中金");
        nayin.put("丙寅", "炉中火");
        nayin.put("丁卯", "炉中火");
        nayin.put("戊辰", "大林木");
        nayin.put("己巳", "大林木");
        nayin.put("庚午", "路旁土");
        nayin.put("辛未", "路旁土");
        nayin.put("壬申", "剑锋金");
        nayin.put("癸酉", "剑锋金");
        nayin.put("甲戌", "山头火");
        nayin.put("乙亥", "山头火");
        nayin.put("丙子", "洞下水");
        nayin.put("丁丑", "洞下水");
        nayin.put("戊寅", "城墙土");
        nayin.put("己卯", "城墙土");
        nayin.put("庚辰", "白腊金");
        nayin.put("辛巳", "白腊金");
        nayin.put("壬午", "杨柳木");
        nayin.put("癸未", "杨柳木");
        nayin.put("甲申", "泉中水");
        nayin.put("乙酉", "泉中水");
        nayin.put("丙戌", "屋上土");
        nayin.put("丁亥", "屋上土");
        nayin.put("戊子", "霹雷火");
        nayin.put("己丑", "霹雷火");
        nayin.put("庚寅", "松柏木");
        nayin.put("辛卯", "松柏木");
        nayin.put("壬辰", "常流水");
        nayin.put("癸巳", "常流水");
        nayin.put("甲午", "沙中金");
        nayin.put("乙未", "沙中金");
        nayin.put("丙申", "山下火");
        nayin.put("丁酉", "山下火");
        nayin.put("戊戌", "平地木");
        nayin.put("己亥", "平地木");
        nayin.put("庚子", "壁上土");
        nayin.put("辛丑", "壁上土");
        nayin.put("壬寅", "金箔金");
        nayin.put("癸卯", "金箔金");
        nayin.put("甲辰", "佛灯火");
        nayin.put("乙巳", "佛灯火");
        nayin.put("丙午", "天河水");
        nayin.put("丁未", "天河水");
        nayin.put("戊申", "大驿土");
        nayin.put("己酉", "大驿土");
        nayin.put("庚戌", "钗钏金");
        nayin.put("辛亥", "钗钏金");
        nayin.put("壬子", "桑松木");
        nayin.put("癸丑", "桑松木");
        nayin.put("甲寅", "大溪水");
        nayin.put("乙卯", "大溪水");
        nayin.put("丙辰", "沙中土");
        nayin.put("丁巳", "沙中土");
        nayin.put("戊午", "天上火");
        nayin.put("己未", "天上火");
        nayin.put("庚申", "石榴木");
        nayin.put("辛酉", "石榴木");
        nayin.put("壬戌", "大海水");
        nayin.put("癸亥", "大海水");
    }

    public String nayin(String key) {
        return nayin.get(key);
    }

    // 由天格、人格、地格数得到三才
    public String getSancai(int tiange, int renge, int dige) {
        return getSancai(tiange) + getSancai(renge) + getSancai(dige);
    }

    public String getSancai(int geshu) {
        switch (geshu % 10) {
            case 1:
                return "木";
            case 2:
                return "木";
            case 3:
                return "火";
            case 4:
                return "火";
            case 5:
                return "土";
            case 6:
                return "土";
            case 7:
                return "金";
            case 8:
                return "金";
            case 9:
                return "水";
            case 10:
                return "水";
            case 0:
                return "水";
        }
        return "";
    }

    public String[] tgdzwx(String[] tgdz) {
        String[] wx = new String[tgdz.length];
        for (int i = 0; i < wx.length; i++) {
            wx[i] = tgdzwx(tgdz[i]);
        }
        return wx;
    }

    // 天干地支转换为五行
    public String tgdzwx(String tgdz) {
        switch (tgdz) {
            case "子":
                return "水";
            case "亥":
                return "水";
            case "寅":
                return "木";
            case "卯":
                return "木";
            case "巳":
                return "火";
            case "午":
                return "火";
            case "申":
                return "金";
            case "酉":
                return "金";
            case "辰":
                return "土";
            case "戌":
                return "土";
            case "丑":
                return "土";
            case "未":
                return "土";
            case "甲":
                return "木";
            case "乙":
                return "木";
            case "丙":
                return "火";
            case "丁":
                return "火";
            case "戊":
                return "土";
            case "己":
                return "土";
            case "庚":
                return "金";
            case "辛":
                return "金";
            case "壬":
                return "水";
            case "癸":
                return "水";
            default:
                return "";
        }
    }

    public String toBig5(String s) {
        return HanLP.convertToTraditionalChinese(s);
    }

    public void a(){
        HanLP.newSegment().enableNameRecognize(true).seg("").get(0);
    }

    public String getPinYin(String s) {
        String r = "";
        for (int i = 0; i < s.length(); i++) {
            char c = s.charAt(i);
            r = r + PinyinHelper.toTongyongPinyinStringArray(c)[0] + " ";
        }
        return r;
    }

    public int getPf(String sc) {
        switch (sc) {
            case "大吉":
                return 12;
            case "吉":
                return 8;
            case "半吉":
                return 5;
            case "大凶":
                return 0;
            case "凶":
                return 1;
            case "半凶":
                return 2;
            case "平":
                return 4;
        }
        return 0;
    }
}
